<template>
  <transition name="fadeIn">
    <div v-show='false'>
      <el-table :id="exportExcelInfo.excelId" :data="tableData" highlight-current-row style="width: 100%"
                :span-method="objectSpanMethod"
                :cell-style="cellStyle"
                :show-summary="showSummary" :summary-method="getSummaries">
        <template v-for="(item,index) in exportExcelArray" >
          <el-table-column v-if="!item.formatterFlag" :prop="item.prop" :label="item.label"
                           :align="item.align" :width="item.width">
            <template slot-scope="scope">
              <span :class="{'redColor':scope.row&&scope.row.showRed}">
                {{scope.row[item.prop]}}
              </span>
            </template>
          </el-table-column>
          <el-table-column v-else :prop="item.prop" :label="item.label"
                           :align="item.align" :width="item.width">
            <template slot-scope="scope">
              <span :class="{'redColor':scope.row&&scope.row.showRed}">
                {{formatter(scope.row[item.prop],item,scope.row,item.prop)}}
              </span>
            </template>
          </el-table-column>
        </template>
        <template v-if="tableMoreList&&tableMoreList.length>0">
          <el-table-column :prop="pItem.value" :label="pItem.label" align="center"
                           v-for="(pItem,pIndex) in tableMoreList" :key="pIndex+'again'">
            <template slot-scope="scope">
              <span
                v-if="pItem.type == 'number'"
                :class="{'redColor':scope.row[tableMoreStr]&&scope.row[tableMoreStr][pIndex]&&scope.row[tableMoreStr][pIndex].timed}">
                {{scope.row[tableMoreStr][pIndex].value|timestampToDay}}
              </span>
              <span
                v-else
                :class="{'redColor':scope.row[tableMoreStr]&&scope.row[tableMoreStr][pIndex]&&scope.row[tableMoreStr][pIndex].timed}">
                {{scope.row[tableMoreStr][pIndex].value}}
              </span>
              <!--                  <span>{{scope.row[pItem.prop]}}</span>-->
            </template>
          </el-table-column>
        </template>
      </el-table>
    </div>
  </transition>
</template>
<script>
import FileSaver from 'file-saver'
import * as XLSX from "xlsx"
import * as XLSXSTYLE from 'xlsx-style'
import {timestampToDay} from '@/utils/util.js'
import reportMin from "@/views/tatisticalReport/tatisticalReport.js"
export default {
  props: {
    exportExcelInfo: {
      type: Object,
      default: {}
    },
    exportExcelArray: {
      type: Array,
      default: () => {
            return []
          }
    },
    tableData: {
      type: Array,
      default: () => {
            return []
          }
    },
    exportExcelHead: {
      type: Array,
      default: () => {
            return []
          }
    },
    // 表格列最后一列，有边框样式，手动去掉
    sheetLast: {
      type: String,
      default: 'AA1'
    },
    // 动态渲染数组
    tableMoreList: {
      type: Array,
      default: () => {
            return []
          }
    },
    tableMoreStr: {
      type: String,
      default: ''
    },
    //  是否显示总计
    showSummary: {
      type: Boolean,
      default: false
    },
    summaryList: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 是否合并小格
    mergeCells: {
      type: Boolean,
      default: false
    },
    // 是否显示小计
    isSubtotal: {
      type: Boolean,
      default: false
    },
    // 合并小格名称
    mergeName: {
      type: String,
      default: ''
    },
    // 导出自定义字体颜色所属字段
    // 导出自定义字体颜色所属字段
    showRedList: {
      type: Array,
      default: () => {
        return []
      }
    },
    showOrangeList: {
      type: Array,
      default: () => {
        return []
      }
    },
    showGreenList: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 导出自定义字体颜色
    customColor: {
      type: String,
      default: 'D63640'
    },
    customGreen: {
      type: String,
      default: '1AD96F'
    },
    customOrange: {
      type: String,
      default: 'f2b400'
    },
  },
  mixins:[reportMin],
  methods: {
    isNull(str) {
      if (str === null || str === undefined || str.length === 0) {
        return true
      }
      return false
    },
    // 样式
    cellStyle({row}){
      if(this.tableMoreList && this.tableMoreList.length > 0){
        this.tableMoreList.map((pItem,pIndex)=>{
          if(row[this.tableMoreStr]&&row[this.tableMoreStr][pIndex]&&row[this.tableMoreStr][pIndex].timed){
            return "color: #e8e917 !important"
          }
        })
      } else {
        // if(row.showRed){
        //   return "color: #D63640 !important"
        // }
      }
    },
    //excel导出
    exportExcel () {
      // 使用 this.$nextTick 是在dom元素都渲染完成之后再执行
      this.$nextTick(function() {
        var xlsxParam = { raw: true } // 导出的内容只做解析，不进行格式转换
        // var wb = XLSX.utils.table_to_book(document.querySelector('#'+this.exportExcelInfo.excelId),xlsxParam)
        // var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })

        //样式1
        // 标记1-开始
        const wb = this.setExlStyle(
          XLSX.utils.table_to_book(
            document.querySelector('#'+this.exportExcelInfo.excelId),
            xlsxParam
          )
        )
        // 有fixed情况
        // const exportTable = document.getElementById(this.exportExcelInfo.excelId).cloneNode(true)
        // exportTable.removeChild(exportTable.querySelector('.el-table__fixed'))
        // // 调用改变样式的方法
        // const wb = this.setExlStyle(
        //   XLSX.utils.table_to_book(
        //     exportTable,
        //     xlsxParam
        //   )
        // )
        // 标记1-结束

        //样式2
        // console.log('wb',wb)
        // this.addRangeBorder(
        //   wb['Sheets']['Sheet1']['!merges'],
        //   wb['Sheets']['Sheet1']
        // )

        //样式3
        // 注意：导出Excel, 注意这里用到的是XLSXSTYLE对象  才会有设置的样式
        const wbout = XLSXSTYLE.write(wb, {
          bookType: 'xlsx', // 生成的文件类型
          bookSST: false,
          type: 'binary'
        })

        try {
          // FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), this.exportExcelInfo.excelName)
          //样式4
          FileSaver.saveAs(new Blob([this.s2ab(wbout)], { type: 'application/octet-stream' }), this.exportExcelInfo.excelName)
        } catch (e) {
          if (typeof console !== 'undefined') console.log(e, wbout)
        }
        return wbout
      })
    },
    //表格formatter数据格式化
    formatter (value,item,row,prop) {
      // console.log('value',value)
      // console.log('item',item)
      // console.log('row',row)
      // console.log('prop',prop)
      //针对table中item多层对象层级的情况
      if(prop.indexOf('.') > 0){
        let temp = prop.split('.')
        // console.log('temp',temp)
        //item中嵌套两层(列表数组)
        if(temp.length == 2){
          let temp = prop.split('.')
          let arry = row[temp[0]]
          let result = ''
          // 多层对象层级的情况是否为数组
          if(Array.isArray(arry)){
            for(let i in arry){
              // console.log('arry[i][temp[1]]',arry[i][temp[1]])
              if(!this.isNull(arry[i][temp[1]])){
                if(item.formatterType == 'common-type'){  //通用类型转换
                  result = arry[i][temp[1]]
                } else if(item.formatterType == 'time-type'){ //时间标准格式化
                  result = timestampToDay(arry[i][temp[1]])
                } else if(item.formatterType == 'amount-type'){ //金额转换
                  result = (arry[i][temp[1]] / 100).toFixed(2)
                }
                return result
              }
            }
          }else{
            // 多层对象层级的情况是否为对象
            if(!this.isNull(row[temp[0]][temp[1]])){
              if(item.formatterType == 'common-type'){  //通用类型转换
                result = row[temp[0]][temp[1]]
              } else if(item.formatterType == 'time-type'){ //时间标准格式化
                result = timestampToDay(row[temp[0]][temp[1]])
              } else if(item.formatterType == 'amount-type'){ //金额转换
                result = (row[temp[0]][temp[1]] / 100).toFixed(2)
              }
              return result
            }
          }
        }
      } else{ //item中无嵌套对象
        let temp = prop.split('.')
        if(item.formatterType == 'common-type'){  //通用类型转换
          let arry = item.formatterInfo
          for(let i in arry){
            if(arry[i].value == value){
              return arry[i].label
            }
          }
        } else if(item.formatterType == 'time-type'){ //时间标准格式化
          // console.log('row[temp[0]])1',row[temp[0]])
          if(!this.isNull(row[temp[0]])){
            // return value.substring(0,value.length - 2)
            return timestampToDay(value)
          }
        } else if(item.formatterType == 'amount-type'){ //金额转换
          return (value / 100).toFixed(2)
        }
      }
    },
    // 设置表格样式5
    setExlStyle(data) {
      // console.log('data',data)
      // const array = Object.keys(data.Sheets.Sheet1)
      const vm = this
      const array = Object.entries(data.Sheets.Sheet1)
      array.forEach(([key, value]) => {
        // 自定义字体颜色
        let col = '000000'
        // 红色
        if(vm.showRedList.includes(value.v) || value.v < 0){
          col = vm.customColor
        }
        //绿色
        if(vm.showGreenList.includes(value.v) || value.v < 0){
          col = vm.customGreen
        }
        // 橙色
        if(vm.showOrangeList.includes(value.v) || value.v < 0){
          col = vm.customOrange
        }
        // 设置每个单元格属性
        if (key.indexOf('!') < 0) {
          data.Sheets.Sheet1[key].s = {
            // 边框
            border: {
              top: { style: 'thin' },
              bottom: { style: 'thin' },
              left: { style: 'thin' },
              right: { style: 'thin' }
            },
            // 字体
            font: {
              sz: 12,
              // 自定义字体颜色
              color: {rgb: col},
            },
            // 居中
            alignment: {
              horizontal: 'center',
              vertical: 'center',
              wrapText: true
            }
          }
        }
      })
      //标记2 start
      // 导出的excel会给(sheetLast)这列两行有边框样式，手动去掉
      // console.log('data.Sheets.Sheet1', data.Sheets.Sheet1)
      let border = {
        top: { style: 'none' },
        bottom: { style: 'none' },
        left: { style: 'thin' },
        right: { style: 'none' }
      }
      if(data.Sheets.Sheet1['!fullref'].indexOf(':') > 0) {
        let sheetLast = data.Sheets.Sheet1['!fullref'].split(':')[1].replace(/[0-9]/g,'') + '1'
        // console.log('sheetLast', sheetLast)
        if(data.Sheets.Sheet1[sheetLast]){
          data.Sheets.Sheet1[sheetLast].s = {
            border: border
          }
        }
        //  是否显示总计
        if(this.showSummary){
          let sheetLast = data.Sheets.Sheet1['!fullref'].split(':')[1]
          // console.log('sheetLast', sheetLast)
          if(data.Sheets.Sheet1[sheetLast]){
            data.Sheets.Sheet1[sheetLast].s = {
              border: border
            }
          }
        }
      }
      //标记2 end

      // 列宽
      data.Sheets.Sheet1['!cols'] = []
      // 行宽
      data.Sheets.Sheet1['!rows'] = []

      // 根据列数设置每一列的列宽  这里table有{{len}}列
      if(this.exportExcelHead&&this.exportExcelHead.length>0){
        data.Sheets.Sheet1['!cols'] = this.exportExcelHead
      }
      // 根据行数设置每一行的高度  这里table有{{len}}行
      let rowsLen = this.tableData.length
      for (let i = 0; i < rowsLen; i++) {
        data.Sheets.Sheet1['!rows'].push({ wpx: 120, wch: 40 })
      }

      // for (let i = 0; i < 6; i++) {
      //   data.Sheets.Sheet1['!cols'].push({ wpx: 120, wch: 20 })
      // }
      // //设置第一列
      // data.Sheets.Sheet1['!cols'][0].wpx = 200
      // console.log('data new',data)
      return data
    },
    // 文件流转换
    s2ab(s) {
      // 如果存在ArrayBuffer对象(es6) 最好采用该对象
      if (typeof ArrayBuffer !== 'undefined') {
        // 1、创建一个字节长度为s.length的内存区域
        const buf = new ArrayBuffer(s.length)
        // 2、创建一个指向buf的Unit8视图，开始于字节0，直到缓冲区的末尾
        const view = new Uint8Array(buf)
        // 3、返回指定位置的字符的Unicode编码
        for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
        return buf
      } else {
        const buf = new Array(s.length)
        for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff
        return buf
      }
    },
    //表格边框：合并单元格时会丢失边框样式
    addRangeBorder(range, ws) {
      console.log('range',range)
      // s:起始位置，e:结束位置
      const arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
      range.forEach((item) => {
        const startRowNumber = Number(item.s.r)
        const startColumnNumber = Number(item.s.c)
        const endColumnNumber = Number(item.e.c)
        const endRowNumber = Number(item.e.r)
        // 合并单元格时会丢失边框样式，例如A1->A4 此时内容在A1 而range内获取到的是从0开始的，所以开始行数要+2
        for (let i = startColumnNumber; i <= endColumnNumber; i++) {
          for (let j = startRowNumber + 2; j <= endRowNumber + 1; j++) {
            ws[arr[i] + j] = {
              s: {
                border: {
                  top: { style: 'thin' },
                  left: { style: 'thin' },
                  bottom: { style: 'thin' },
                  right: { style: 'thin' }
                }
              }
            }
          }
        }
      })
      return ws
    },
  }
};
</script>
